package cn.edu.bs.service;

import cn.edu.bs.dao.Example;
import cn.edu.bs.web.request.BaseCommand;
import cn.edu.bs.web.vo.BaseVO;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author bs
 */
public interface BaseService<T, C extends T, E extends Example, V extends BaseVO, P extends BaseCommand> {

    /**
     * 高级条件查询实体个数
     *
     * @param example 条件
     * @return 个数
     */
    long countByExample(E example);

    /**
     * 高级条件删除实体
     *
     * @param example 条件
     * @return
     */
    int deleteByExample(E example);

    /**
     * 根据主键删除实体
     *
     * @param id 主键
     * @return
     */
    int deleteByPrimaryKey(Integer id);

    /**
     * 保存实体，所有字段
     *
     * @param record 实体
     * @return
     */
    int insert(T record);

    /**
     * 保存实体，部分字段
     *
     * @param record 实体
     * @return
     */
    int insertSelective(T record);

    /**
     * 高级条件查询
     *
     * @param example 条件
     * @return 实体集合
     */
    List<T> selectByExample(E example);

    /**
     * 主键查询
     *
     * @param id 主键
     * @return 实体
     */
    T selectByPrimaryKey(Integer id);

    /**
     * 通过高级查询实现实体的部分更新
     *
     * @param record  实体，可部分设值
     * @param example 条件
     * @return
     */
    int updateByExampleSelective(@Param("record") T record, @Param("example") E example);

    /**
     * 通过高级查询实现实体的完全更新
     *
     * @param record  实体，全部设值
     * @param example 条件
     * @return
     */
    int updateByExample(@Param("record") T record, @Param("example") E example);

    /**
     * 通过主键查询实现实体的部分更新
     *
     * @param record 实体，可部分设值，但主键必须有值
     * @return
     */
    int updateByPrimaryKeySelective(T record);

    /**
     * 通过主键查询实现实体的完全更新
     *
     * @param record 实体，全部设值
     * @return
     */
    int updateByPrimaryKey(T record);

    /**
     * 将命令对象转换为实体对象
     *
     * @param command 命令对象
     * @return 实体对象
     */
    T transformCommandToEntity(P command);

    /**
     * 将实体对象转换成数据传输对象
     *
     * @param entity 实体对象
     * @return 数据传输对象
     */
    V transformEntityToVO(T entity);

    /**
     * 将实体扩展对象转换成数据传输对象
     *
     * @param custom 实体扩展对象
     * @return 数据传输对象
     */
    V transformCustomToVO(C custom);

    /**
     * 将实体对象集合转换成数据传输对象集合
     *
     * @param entities 实体对象集合
     * @return 数据传输对象集合
     */
    List<V> transformEntitiesToTOs(List<T> entities);

    /**
     * 将实体扩展对象集合转换成数据传输对象集合
     *
     * @param customs 实体扩展对象集合
     * @return 数据传输对象集合
     */
    List<V> transformCustomsToTOs(List<C> customs);
}
